# -*- coding: utf-8 -*-
# https://blog.csdn.net/weixin_52040868
# 公众号：测个der
# 微信：qing_an_an

import re
import os
import pandas as pd
import datetime
from PySide6.QtCore import QThread
from PySide6.QtWidgets import QVBoxLayout
import pyqtgraph as pg
from pyqtgraph import DateAxisItem, PlotDataItem, AxisItem, PlotWidget


class LogParsingThread(QThread):

    def __init__(self, args):
        super().__init__()
        self.args = args
        self.log = LogParsing()

    def run(self):
        self.log.argValue = self.args.run()
        self.log.getFilePath(self.log.argValue.get("path"))
        self.log.reInfoParsing()
        self.exec_()

    def stop(self):
        # 停止线程的方法
        self.quit()
        self.wait()


class UnpackDataThread(QThread):

    def __init__(self, args, ui):
        super().__init__()
        self.ui = ui
        self.args = args
        self.unpackDataChart = UnpackDataChart(self.ui)

    def run(self):
        self.unpackDataChart.argValue = self.args.run()
        self.unpackDataChart.run()
        self.exec_()

    def stop(self):
        # 停止线程的方法
        self.quit()
        self.wait()


class Args:
    Path: str = r''
    graphColIndexList: list[str] = []
    dataColumnListValue: list[str] = []
    needSheetName: list[str] = []

    def run(self):
        argsDict = {
            "path": self.Path,
            "needSheetName": self.needSheetName,
            "graphColIndexList": self.graphColIndexList,
            "dataColumnListValue": self.dataColumnListValue
        }
        return argsDict


def readExcelSheets_Headers(path: str):
    """读取表单以及每个表单的第一行数据"""
    dataDict = {}
    excelFile = pd.ExcelFile(path)
    # 获取所有表单的名称
    sheetNames = excelFile.sheet_names
    dataDict["sheetNames"] = sheetNames
    # 遍历每个表单的数据
    for sheet_name in sheetNames:
        # 获取表头数据列表
        df = excelFile.parse(sheet_name, nrows=1)
        headers = df.columns.tolist()
        # 表单与头部数据
        dataDict[sheet_name] = headers
    return dataDict


def autoReadLog(func):
    def wrapper(*args, **kwargs):
        self = args[0]
        path = self.argValue.get("path")
        with open(path, 'r', encoding='utf-8') as r:
            self.texts = r.read()
        return func(*args, **kwargs)

    return wrapper


class LogParsing:
    def __init__(self):
        self.texts = ' '
        self.dataDict = {}
        self.argValue = None
        self.path = ''

    def getFilePath(self, path):

        """
        :return: 文件路径，如果存在即删除
        """
        if '/' in path:
            path = path.split('/')
        # if '\\' in path:
        #     path = path.split("\\")
            del path[-1]
            self.path = '/'.join(path)
        xlsxPath = self.path + "/日志解析数据.xlsx"
        for (root, dirs, files) in os.walk(self.path, topdown=True):
            if xlsxPath in files:
                os.remove(xlsxPath)

    @autoReadLog
    def reInfoParsing(self):
        """
        :return: info数据筛选
        """
        values = re.findall('<.*?>', self.texts)
        orderValues = list(dict.fromkeys(values))
        print(orderValues)
        for order, num in zip(orderValues, range(len(orderValues) - 1)):
            pattern = r"{}([\s\S]*?){}".format(re.escape(values[num]), re.escape(values[num + 1]))
            datas = re.findall(pattern, self.texts)
            for data in datas:
                # dataValue = re.findall('(.*])(\w*\s*):\s*(.*)', data)
                dataValue = re.findall('\[(.*)\]\s*(\w*\s*)\s*:\s*([^\s]*)', data)
                if order not in self.dataDict:
                    self.dataDict[order] = {}
                    self.dataDict[order]['time'] = []

                for dataDict in dataValue:
                    time, key, value = dataDict[0], dataDict[1].strip(), dataDict[2]
                    if key not in self.dataDict[order]:
                            self.dataDict[order][key] = []
                    self.dataDict[order][key].append(value)
                try:
                    self.dataDict[order]['time'].append(time)
                except:
                    pass

        self.writerInfoExcel(self.path + "/日志解析数据.xlsx")

    def writerInfoExcel(self, filePath: str):
        """`
        :param filePath: # 存储路径
        :return:   做数据图
        """
        with pd.ExcelWriter(filePath) as writer:
            for sheet_name, data in self.dataDict.items():
                df = pd.DataFrame(data)
                for column in df.columns:
                    if df[column].dtype == object:  # 检查列的数据类型是否为对象类型
                        try:
                            # 尝试将值转换为浮点数
                            df[column] = df[column].astype(float)
                        except ValueError:
                            # 转换失败，将值保持为字符串
                            df[column] = df[column].astype(str)
                df.to_excel(writer, sheet_name=sheet_name, index=False)

    # @autoReadLog
    # def measData(self):
    #     """
    #     :param  meas数据筛选加持
    #     :return:  excel Files
    #     """
    #     values = re.findall('\[(.*)\](.*)', self.texts)
    #     if all([value for value in values if ',' in value[1]]):
    #         values = re.findall('\[(.*)\](\w*:\d*),\s*(\w*:\d*)', self.texts)
    #         if meas not in self.dataDict:
    #             self.dataDict[meas] = {}
    #         timeList, v1List, v2List = [], [], []
    #         for key in values:
    #             time, v1, v2 = key[0], key[1].split(':'), key[2].split(':')
    #             timeList.append(time)
    #             v1List.append(v1[1])
    #             v2List.append(v2[1])
    #         try:
    #             self.dataDict[meas] = dict(zip(['time', v1[0], v2[0]], [timeList, v1List, v2List]))
    #             self.writerInfoExcel(saveExcelPath)  # 存储路径
    #         except:
    #             raise "数据格式有误，请检查日志是否符合"
    # self.dataDict["meas"] = {"time": timeList, "v1": v1List, "v2": v2List}

    # def graph(self, writer: pd.ExcelWriter, sheetName: str, df: pd.DataFrame,
    #           graphIndexList: list, dataColumnListValue: list, needSheetName: str):
    #     workbook = writer.book
    #     # 指定要绘制曲线图的order和数据列名
    #     if sheetName == needSheetName:
    #         worksheet = writer.sheets[sheetName]  # 获取表单
    #         chart = workbook.add_chart({'type': 'line'})  # 折线图
    #         chart.set_size({'width': 700, 'height': 450})  # 设置宽度为480像素，高度为320像素
    #
    #         # 获取数据范围
    #         num_rows = len(df)
    #         # 以时间为X轴
    #         x_column = 'A2:A{}'.format(num_rows + 1)
    #
    #         # 添加曲线图数据系列
    #         for k, v in zip(graphIndexList, dataColumnListValue):
    #             try:
    #                 chart.add_series({'categories': x_column,
    #                                   'values': v.format(num_rows + 1),
    #                                   'name': k,
    #                                   'line': {'width': 0.9}
    #                                   })
    #             except:
    #                 raise "请检查graphIndexList或dataColumnListValue值是否正确"
    #         # 设置图表标题、X轴标签和Y轴标签
    #         chart.set_title({'name': sheetName + "DataGraph"})
    #         chart.set_x_axis({'name': 'Time/Hour-minute-second'})
    #         # major_unit设置Y轴刻度线间距
    #         chart.set_y_axis({'name': "Data/Graph", 'major_unit': 5})
    #
    #         # 将图表插入到工作表
    #         worksheet.insert_chart('F2', chart)


class TimeAxisItem(AxisItem):
    def __init__(self, orientation, *args, **kwargs):
        super().__init__(orientation, *args, **kwargs)

    def tickStrings(self, values, scale, spacing):
        return [datetime.datetime.fromtimestamp(value).strftime("%H:%M:%S.%f")[:-3] for value in values]


class UnpackDataChart:
    def __init__(self, ui):
        self.ui = ui
        self.argValue = None
        self.layout = QVBoxLayout()
        self.ui.widget_3.setLayout(self.layout)

        # 创建绘图窗口
        self.plot_widget = pg.PlotWidget()
        self.layout.addWidget(self.plot_widget)

    def read(self):
        # 路径
        path: str = self.argValue.get("path")
        # 表单名称
        sheetNames = self.argValue.get("needSheetName")
        # 表单行首数据
        sheetNamecolIndexs: list[str] = self.argValue.get("graphColIndexList")
        # 表单的值
        sheetNamecolDatas = self.argValue.get("dataColumnListValue")

        df = pd.read_excel(path, sheet_name=sheetNames)
        time_data = df.iloc[:, 0]

        column_data = df.loc[:, sheetNamecolIndexs]
        column_data_list = [value for sublist in column_data.values.tolist() for value in sublist]  # 将列数据转换为列表
        return time_data.tolist(), column_data_list

    def run(self):
        datas = self.read()
        time = datas[0]
        value = datas[1]
        # 创建绘图曲线
        plot = self.plot_widget.plot(x=[float(i.replace(":","")) for i in time], y=value, pen='m')

        # 添加绘图曲线和时间轴到绘图窗口
        self.plot_widget.addItem(plot)
        self.plot_widget.show()


"""////////////////////////////原写入图表脚本///////////////////////////////////"""
# -*- coding: utf-8 -*-
# https://blog.csdn.net/weixin_52040868
# 公众号：测个der
# 微信：qing_an_an

# import re
# import os
# import pandas as pd
#
# """
# logFilePath -----> 日志存在的位置
# saveExcelPath ------> 日志需要存在哪
# graphIndexList  --------> 作图的曲线名称
# dataColumnListValue  ------------> 需要的数据列有哪些，支持2个以上
# needSheetName ----------------> 表单名称，作为判断，如果是meas，原封不动，info数据需要<batterry>
# meas ---------------------> 无关紧要参数
# """
#
#
# logFilePath = r"C:\Users\admin\Desktop\Log\系6号口20230704_09_42_31.log"
# # logFilePath: str = r"C:\Users\admin\Desktop\Log\系6号口20230703_16_54_42.log"
# workPath: str = r'C:\Users\admin\Desktop'
# saveExcelPath: str = r'C:\Users\admin\Desktop\日志数据解析.xlsx'
# graphIndexList: list[str] = ["tpwr"]
# dataColumnListValue: list[str] = ["E2:E{}"]
# needSheetName: str = '<batterry>'
# meas: str = "meas"
#
#
# def autoReadLog(func):
#     def wrapper(*args, **kwargs):
#         self = args[0]
#         with open(logFilePath, 'r', encoding='utf-8') as r:
#             self.texts = r.read()
#         return func(*args, **kwargs)
#
#     return wrapper
#
#
# class LogParsing:
#     def __init__(self):
#         self.texts = ' '
#         self.dataDict = {}
#         self.getFilePath()
#
#     def getFilePath(self):
#         """
#         :return: 文件路径，如果存在即删除
#         """
#         for (root, dirs, files) in os.walk(workPath, topdown=True):
#             if saveExcelPath in files:
#                 os.remove(saveExcelPath)
#
#     @autoReadLog
#     def reInfoParsing(self):
#         """
#         :return: info数据筛选
#         """
#         values = re.findall('<.*?>', self.texts)
#         orderValues = list(dict.fromkeys(values))
#         for order, num in zip(orderValues, range(len(orderValues) - 1)):
#             pattern = r"{}([\s\S]*?){}".format(re.escape(values[num]), re.escape(values[num + 1]))
#             datas = re.findall(pattern, self.texts)
#             for data in datas:
#                 # dataValue = re.findall('(.*])(\w*\s*):\s*(.*)', data)
#                 dataValue = re.findall('\[(.*)\](\w*\s*):\s*([^\s]*)', data)
#                 if order not in self.dataDict:
#                     self.dataDict[order] = {}
#                     self.dataDict[order]['time'] = []
#                 for dataDict in dataValue:
#                     time, key, value = dataDict[0], dataDict[1].strip(), dataDict[2]
#                     if key not in self.dataDict[order]:
#                         self.dataDict[order][key] = []
#                     self.dataDict[order][key].append(value)
#                 self.dataDict[order]['time'].append(time)
#
#         self.writerInfoExcel(saveExcelPath)
#
#     @autoReadLog
#     def measData(self):
#         """
#         :param  meas数据筛选加持
#         :return:  excel Files
#         """
#         values = re.findall('\[(.*)\](.*)', self.texts)
#         if all([value for value in values if ',' in value[1]]):
#             values = re.findall('\[(.*)\](\w*:\d*),\s*(\w*:\d*)', self.texts)
#             if meas not in self.dataDict:
#                 self.dataDict[meas] = {}
#             timeList, v1List, v2List = [], [], []
#             for key in values:
#                 time, v1, v2 = key[0], key[1].split(':'), key[2].split(':')
#                 timeList.append(time)
#                 v1List.append(v1[1])
#                 v2List.append(v2[1])
#             try:
#                 self.dataDict[meas] = dict(zip(['time', v1[0], v2[0]], [timeList, v1List, v2List]))
#                 self.writerInfoExcel(saveExcelPath)  # 存储路径
#             except:
#                 raise "数据格式有误，请检查日志是否符合"
#             # self.dataDict["meas"] = {"time": timeList, "v1": v1List, "v2": v2List}
#
#     def writerInfoExcel(self, filePath: str):
#         """
#         :param filePath: # 存储路径
#         :return:   做数据图
#         """
#         with pd.ExcelWriter(filePath) as writer:
#             for sheet_name, data in self.dataDict.items():
#                 df = pd.DataFrame(data)
#                 for column in df.columns:
#                     if df[column].dtype == object:  # 检查列的数据类型是否为对象类型
#                         try:
#                             # 尝试将值转换为浮点数
#                             df[column] = df[column].astype(float)
#                         except ValueError:
#                             # 转换失败，将值保持为字符串
#                             df[column] = df[column].astype(str)
#                 print(sheet_name)
#                 df.to_excel(writer, sheet_name=sheet_name, index=False)
#                 self.graph(writer=writer, sheetName=sheet_name, df=df)
#
#     def graph(self, writer: pd.ExcelWriter, sheetName: str, df: pd.DataFrame, ):
#         workbook = writer.book
#         # 指定要绘制曲线图的order和数据列名
#         if sheetName == needSheetName:
#             worksheet = writer.sheets[sheetName]  # 获取表单
#             chart = workbook.add_chart({'type': 'line'})  # 折线图
#             chart.set_size({'width': 700, 'height': 450})  # 设置宽度为480像素，高度为320像素
#
#             # 获取数据范围
#             num_rows = len(df)
#             # 以时间为X轴
#             x_column = 'A2:A{}'.format(num_rows + 1)
#
#             # 添加曲线图数据系列
#             for k, v in zip(graphIndexList, dataColumnListValue):
#                 try:
#                     chart.add_series({'categories': x_column,
#                                       'values': v.format(num_rows + 1),
#                                       'name': k,
#                                       'line': {'width': 0.9}
#                                       })
#                 except:
#                     raise "请检查graphIndexList或dataColumnListValue值是否正确"
#             # 设置图表标题、X轴标签和Y轴标签
#             chart.set_title({'name': sheetName + "DataGraph"})
#             chart.set_x_axis({'name': 'Time/Hour-minute-second'})
#             # major_unit设置Y轴刻度线间距
#             chart.set_y_axis({'name': "Data/Graph",'major_unit': 5})
#
#             # 将图表插入到工作表
#             worksheet.insert_chart('F2', chart)
#
#
# if __name__ == '__main__':
#     logParsing = LogParsing()
#     logParsing.reInfoParsing()   # info 数据打开
# logParsing.measData()  # meas 数据打开
